import json

from django.db import transaction, IntegrityError
from django.db.models import Count, Q
from django_filters.rest_framework import DjangoFilterBackend
from drf_spectacular.utils import extend_schema
from rest_framework import status, filters
from rest_framework.decorators import action
from rest_framework.response import Response

# Create your views here.
from apps.common.models import Pagination
from apps.data.schemas import DownloadResponse, UploadRequest, UploadResponse, UploadPhotoResponse
from apps.opoc.filters import Opoc_InspectionRecordsFilter
from apps.opoc.models import Opoc_InspectionRecord, Opoc_InspectionPhoto
from apps.opoc.serializers import Opoc_InspectionRecordsSerializer, Opoc_InspectionPhotosSerializer
from extensions.exceptions import ValidationError
from extensions.permissions import IsAuthenticated
from extensions.serializers import BaseSerializer
from extensions.viewsets import *
from apps.opoc.filters import *
from apps.opoc.models import *
from apps.opoc.serializers import *
from apps.system.models import User

import logging

logger = logging.getLogger(__name__)


class Opoc_RecordsViewSet(ModelViewSet, ExportMixin, ImportMixin):
    """一人一码"""
    queryset = Opoc_Records.objects.all()
    serializer_class = Opoc_RecordsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_RecordsFilter
    search_fields = ['company__name', 'name', 'id_number', 'phone']
    select_related_fields = ['company', 'filled_by', 'next_checker',
                             'climb_high_img','electrician_img','safety_officer_img','other_person_img',
                             'construction_contract_pdf','insurance_pdf','safety_responsibility_pdf','safety_education_pdf',
                             'safety_disclosure_pdf','service_order_pdf','task_dispatch_pdf','labor_service_unit',
                             ]
    prefetch_related_fields = ['check_records']
    ordering_fields = ['id', 'name','is_effective','add_time']

    def get_queryset(self):
        # queryset = super().get_queryset().filter(team=self.team)
        certificate_holding = self.request.query_params.get('certificate_holding', None)
        query=Q()
        if certificate_holding:
            query = query & Q(certificate_holding__contains=int(certificate_holding))
        queryset = Opoc_Records.objects.filter(query)
        return queryset

    # def add_record(self,serializer):
    #     opoc = serializer.save()
    #     opoc_check = OpocCheck.objects.create(
    #         opoc=opoc, check_user=self.user,
    #         opinion=self.request.data['opinion'],
    #         is_agree=self.request.data['is_agree'])
    #     opoc.check_records.add(opoc_check)
    #
    # @transaction.atomic
    # def perform_create(self,serializer):
    #     self.add_record(serializer)

    # @transaction.atomic
    # def perform_update(self, serializer):
    #     self.add_record(serializer)


    @action(detail=False, methods=['get'])
    def waitMeModify(self, request, *args, **kwargs):
        """待我修改"""
        query =Q(filled_by=self.user) & Q(is_effective=-1)
        queryset = Opoc_Records.objects.filter(query)
        result = queryset.aggregate(
            total_count=Count('name')
        )
        return Response(data=result, status=status.HTTP_200_OK)

    @action(detail=False, methods=['get'])
    def waitMeCheck(self, request, *args, **kwargs):
        """待我审核"""
        query =Q(next_checker=self.user) & Q(is_effective=0)
        queryset = Opoc_Records.objects.filter(query)
        result = queryset.aggregate(
            total_count=Count('name')
        )
        return Response(data=result, status=status.HTTP_200_OK)


    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def import_template(self, request, *args, **kwargs):
        """导入模板"""

        return self.get_template_response(Opoc_RecordsImportSerializer)


    @extend_schema(request=UploadRequest, responses={200: UploadResponse})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def import_data(self, request, *args, **kwargs):
        """导入数据"""

        request_serializer = UploadRequest(data=request.data)
        request_serializer.is_valid(raise_exception=True)
        validated_data = request_serializer.validated_data

        import_serializer = self.load_data(validated_data['file'], Opoc_RecordsImportSerializer)
        if not import_serializer.is_valid(raise_exception=False):
            raise ValidationError('数据错误')

        Opoc_items = import_serializer.validated_data
        Opoc_set = Opoc_Records.objects.all()
        update_count =0
        creat_count = 0
        for Opoc_item in Opoc_items:
            # client_item['company'] = self.company
            Opoc_item['filled_by'] = self.user
            Opoc_item['company'] = self.user.company
            Opoc_item['step'] = 1#导入的数据默认填报步骤已完成
            Opoc_item['is_effective'] = -1 #导入的数据默认为待修改
            # query = Q(permissions__contains=['Check_project_me_one']) & Q(company=self.user.company)
            # Opoc_item['next_checker'] = User.objects.filter(query)[0]
            Opoc_item['next_checker'] = self.user
            Opoc_item['certificate_holding'] = json.loads(Opoc_item['certificate_holding'])
            query=Q(id=Opoc_item['labor_service_unit'])
            Opoc_item['labor_service_unit'] = Labor_service_unit.objects.filter(query)[0]
            pdf_items=['construction_contract_pdf','insurance_pdf','safety_responsibility_pdf','safety_education_pdf',
                       'safety_disclosure_pdf','service_order_pdf','task_dispatch_pdf']
            for pdf_item in pdf_items:
                Opoc_item[pdf_item] =self.get_pdfinstance(Opoc_item,pdf_item)
            for opoc in Opoc_set:
                if opoc.id_number == Opoc_item['id_number']:
                    idIndb = Opoc_Records.objects.filter(id=opoc.id).values()
                    Opoc_item['id']=opoc.id
                    idIndb.update(**Opoc_item)
                    update_count +=1
                    opoc_res = Opoc_Records.objects.filter(id=opoc.id)[0]
                    opoc_check = OpocCheck.objects.create(
                        opoc=opoc_res, check_user=self.user,
                        opinion='导入修改。',
                        is_agree=True)
                    opoc_res.check_records.add(opoc_check)
                    break
            else:
                opoc_res=Opoc_Records.objects.create(**Opoc_item)
                creat_count += 1
                opoc_check = OpocCheck.objects.create(
                    opoc=opoc_res, check_user=self.user,
                    opinion='导入新增。',
                    is_agree=True)
                opoc_res.check_records.add(opoc_check)

        return Response(status=status.HTTP_200_OK,data={'update_count':update_count,'creat_count':creat_count})

    def get_pdfinstance(self,Opoc_item,pdf_type):
        if pdf_type in Opoc_item:
            query = Q(id=Opoc_item[pdf_type])
            Opoc_item[pdf_type] = Common_Pdfs.objects.filter(query)[0]
            return Opoc_item[pdf_type]
        return None


class Opoc_RecordsImageViewSet(ModelViewSet):
    """Opoc个人images"""

    serializer_class = Opoc_Certificate_ImgsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_Certificate_ImgsFilter
    search_fields = ['name']
    select_related_fields = ['filled_by']
    ordering_fields = ['id', 'name', 'add_time']
    queryset = Opoc_Certificate_Imgs.objects.all()

    @transaction.atomic
    def perform_destroy(self, instance):
        instance.file.delete(save=False)
        instance.delete()
        Response(status=status.HTTP_204_NO_CONTENT)


class Opoc_CommonPdfsViewSet(ModelViewSet):
    """Opoc公共pdf"""

    serializer_class = Opoc_Common_PdfsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_Common_PdfsFilter
    search_fields = ['company__name', 'name']
    select_related_fields = ['company', 'filled_by']
    ordering_fields = ['id', 'name', 'add_time']
    queryset = Common_Pdfs.objects.all()

    @transaction.atomic
    def perform_destroy(self, instance):
        instance.file.delete(save=False)
        instance.delete()
        Response(status=status.HTTP_204_NO_CONTENT)


class Opoc_InspectionPhotosViewSet(ModelViewSet):
    """Opoc检查记录图片"""

    serializer_class = Opoc_InspectionPhotosSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    search_fields = ['company__name', 'name']
    select_related_fields = ['company', 'filled_by']
    ordering_fields = ['id', 'name', 'add_time']
    queryset = Opoc_InspectionPhoto.objects.all()

    @transaction.atomic
    def perform_destroy(self, instance):
        instance.file.delete(save=False)
        instance.delete()
        Response(status=status.HTTP_204_NO_CONTENT)


class Opoc_InspectionRecordsViewSet(ModelViewSet):
    """Opoc检查记录"""

    serializer_class = Opoc_InspectionRecordsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_InspectionRecordsFilter
    search_fields = ['inspection_location', 'description','opoc_record__name']
    select_related_fields = ['opoc_record', 'inspector']
    ordering_fields = ['id', 'name', 'add_time']
    queryset = Opoc_InspectionRecord.objects.all()
    #
    # @extend_schema(responses={200: UploadPhotoResponse})
    # @action(detail=False, methods=['post'])
    # def create_inspection_record(request):
    #     record_data = request.data.copy()
    #     photos = record_data.pop('photos', None)
    #
    #     record_serializer = Opoc_InspectionRecordsSerializer(data=record_data)
    #     if not record_serializer.is_valid():
    #         return Response(record_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #
    #     record = record_serializer.save()
    #
    #     class Opoc_InspectionPhotosSerializer(BaseSerializer):
    #         class Meta:
    #             model = Opoc_InspectionPhoto
    #             fields = '__all__'
    #     if photos:
    #         for photo in photos:
    #             photo_serializer = Opoc_InspectionPhotosSerializer(data={'record': record.id, 'photo': photo})
    #             if photo_serializer.is_valid():
    #                 photo_serializer.save()
    #             else:
    #                 # delete the created InspectionRecord instance if photo is invalid
    #                 record.delete()
    #                 return Response(photo_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #
    #     return Response(record_serializer.data, status=status.HTTP_201_CREATED)


class Opoc_Labor_service_unitsViewSet(ModelViewSet,ImportMixin):
    """Opoc劳务单位"""
    serializer_class = Opoc_Labor_service_unitsSerializer
    pagination_class = Pagination
    permission_classes = [IsAuthenticated]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = Opoc_Labor_service_unitsFilter
    search_fields = ['company__name', 'name','id']
    select_related_fields = ['company', 'filled_by']
    ordering_fields = ['id', 'name', 'add_time']
    queryset = Labor_service_unit.objects.all()

    @extend_schema(responses={200: DownloadResponse})
    @action(detail=False, methods=['get'])
    def import_template(self, request, *args, **kwargs):
        """导入模板"""

        return self.get_template_response(Labor_service_unitImportExportSerializer)

    @extend_schema(request=UploadRequest, responses={200: UploadResponse})
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def import_data(self, request, *args, **kwargs):
        """导入数据"""

        request_serializer = UploadRequest(data=request.data)
        request_serializer.is_valid(raise_exception=True)
        validated_data = request_serializer.validated_data

        import_serializer = self.load_data(validated_data['file'], Labor_service_unitImportExportSerializer)
        if not import_serializer.is_valid(raise_exception=False):
            raise ValidationError('数据错误')

        labor_service_unit_items = import_serializer.validated_data
        labor_service_unit_set = Labor_service_unit.objects.all()
        create_labor_service_unit_set = []
        update_labor_service_unit_set = []
        for labor_service_unit_item in labor_service_unit_items:
            labor_service_unit_item['filled_by'] = self.user
            labor_service_unit_item['company'] = self.user.company
            for labor_service_unit in labor_service_unit_set:
                if labor_service_unit.name == labor_service_unit_item['name']:
                    update_labor_service_unit_set.append(labor_service_unit)
                    for key, value in labor_service_unit_item.items():
                        setattr(labor_service_unit, key, value)
                    break
            else:
                create_labor_service_unit_set.append(Labor_service_unit(**labor_service_unit_item))
        else:
            try:
                Labor_service_unit.objects.bulk_create(create_labor_service_unit_set)
                Labor_service_unit.objects.bulk_update(update_labor_service_unit_set,
                                              Labor_service_unitImportExportSerializer.Meta.fields)
            except IntegrityError:
                raise ValidationError('有名称重复的劳务单位')

        return Response(status=status.HTTP_200_OK,data={'update_count':10,'creat_count':20})




